#ifndef SESSION_H
#define SESSION_H

// C++ lib import
#include <functional>

// Qt lib import
#include <QObject>
#include <QSharedPointer>
#include <QPointer>
#include <QVector>
#include <QMap>
#include <QSet>
#include <QMutex>
#include <QHostAddress>

#include <QTcpSocket>
#include <QLocalSocket>

class QIODevice;
class QTcpServer;
class QLocalServer;
class QThreadPool;
class QHostAddress;
class QTimer;
class QImage;

class Session : public QObject
{
	Q_OBJECT

public:
	Session(const QPointer< QIODevice > & tcpSocket, QObject * parent = 0);

	~Session();

	inline void setHandleAcceptedCallback(const std::function< void(const QPointer< Session > &) > &callback)
	{
		handleAcceptedCallback_ = callback;
	}

	inline QString requestMethodToken() const { return requestMethodToken_; }

	inline QString requestUrl() const { return requestUrl_; }

	inline QString requestCrlf() const { return requestCrlf_; }

	inline QMap< QString, QString > headersData() const { return headersData_; }

	inline QByteArray requestRawData() const { return requestRawData_; }

	public slots:
	void replyText(const QString &replyData);

	void replyJsonObject(const QJsonObject &jsonObject);

	void replyJsonArray(const QJsonArray &jsonArray);

	void replyFile(const QString &filePath);

	void replyImage(const QImage &image);

private:
	void inspectionBufferSetup1();

	void inspectionBufferSetup2();

private:
	QPointer< QIODevice > ioDevice_;
	std::function< void(const QPointer< Session > &) > handleAcceptedCallback_;
	QSharedPointer< QTimer > timerForClose_;

	QByteArray buffer_;

	QString requestMethodToken_;
	QString requestUrl_;
	QString requestCrlf_;

	QMap< QString, QString > headersData_;
	bool headerAcceptedFinish_ = false;

	QByteArray requestRawData_;

	qint64 waitWrittenByteCount_ = 0;
	QSharedPointer< QIODevice > ioDeviceForReply_;
};


#endif // SESSION_H
